package com.hc.java.threadpool;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * A、B、G先执行，C依赖A、B、G，D依赖B，E依赖C、G，F依赖A
 *
 * @author huangchao E-mail:fengquan8866@163.com
 * @version 创建时间：2024/6/17 11:57
 */
public class CompletableFuture多依赖任务执行 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 假设A, B, C, D, E, F, G是返回某个结果的异步操作
        CompletableFuture<String> futureA = CompletableFuture.supplyAsync(() -> {
            // 模拟A任务执行
            System.out.println("Executing A");
            sleep(500);
            return "Result A";
        });

        CompletableFuture<String> futureB = CompletableFuture.supplyAsync(() -> {
            // 模拟B任务执行
            System.out.println("Executing B");
            sleep(200);
            return "Result B";
        });

        CompletableFuture<String> futureG = CompletableFuture.supplyAsync(() -> {
            // 模拟G任务执行
            System.out.println("Executing G");
            return "Result G";
        });

        // C依赖A和B
        CompletableFuture<String> futureC = CompletableFuture.allOf(futureA, futureB)
                .thenApplyAsync(v -> {
                    try {
                        String resultA = futureA.get(); // 获取A的结果
                        String resultB = futureB.get(); // 获取B的结果
                        // 模拟C任务执行
                        System.out.println("Executing C with Result A: " + resultA + " and Result B: " + resultB);
                        sleep(600);
                        return "Result C";
                    } catch (Exception e) {
                        throw new IllegalStateException(e);
                    }
                });

        // D依赖B，所以我们可以直接使用B的future
        CompletableFuture<String> futureD = futureB.thenApplyAsync(bResult -> {
            // 模拟D任务执行
            System.out.println("Executing D with Result B: " + bResult);
            sleep(300);
            return "Result D";
        });

        // E依赖C和G
        CompletableFuture<String> futureE = CompletableFuture.allOf(futureC, futureG)
                .thenApplyAsync(v -> {
                    try {
                        String resultC = futureC.get(); // 获取C的结果
                        String resultG = futureG.get(); // 获取G的结果
                        // 模拟E任务执行
                        System.out.println("Executing E with Result C: " + resultC + " and Result G: " + resultG);
                        sleep(200);
                        return "Result E";
                    } catch (Exception e) {
                        throw new IllegalStateException(e);
                    }
                });

        // F依赖A，所以我们可以直接使用A的future
        CompletableFuture<String> futureF = futureA.thenApplyAsync(aResult -> {
            // 模拟F任务执行
            System.out.println("Executing F with Result A: " + aResult);
            sleep(300);
            return "Result F";
        });

        // 等待所有任务完成（如果需要的话）
        CompletableFuture.allOf(futureC, futureD, futureE, futureF).get();

        // 这里可以添加额外的逻辑来处理任务完成后的结果，如果需要的话
        System.out.println("=============我跑完了");
    }

    private static void sleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
